﻿using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Reflection;

namespace SenGe.Domain.Utils
{
    /// <summary>
    /// 枚举帮助类
    /// </summary>
    public static class EnumUtil
    {
        /// <summary>
        /// 显示枚举对象的显示名称
        /// </summary>
        /// <param name="enum">枚举对象</param>
        /// <returns></returns>
        public static string ToDisplayName(this Enum @enum)
        {
            try
            {
                Type enumType = @enum.GetType();
                FieldInfo? fieldInfo = enumType.GetField(@enum.ToString());
                if (fieldInfo != null)
                {
                    DisplayAttribute? attrDisplay = fieldInfo.GetCustomAttribute<DisplayAttribute>();
                    if (attrDisplay?.Name?.Length > 0)
                    {
                        return attrDisplay.Name;
                    }
                }
            }
            catch { }
            return @enum.ToString();
        }

        /// <summary>
        /// 通过枚举值获取枚举对象的显示名称
        /// 默认Display优先级大于Description
        /// </summary>
        /// <typeparam name="T">枚举对象</typeparam>
        /// <param name="val">枚举值</param>
        /// <returns></returns>
        public static string GetEnumDisplayNameByValue<T>(int val) where T : struct
        {
            try
            {
                Type enumType = typeof(T);
                if (enumType.IsEnum)
                {
                    FieldInfo[] fieldList = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
                    if (fieldList?.Length > 0)
                    {
                        object? enumObj;
                        DisplayAttribute[] arrDisplayNameAttr;
                        DisplayAttribute attrDisplay;
                        DescriptionAttribute[] arrDescriptionAttr;
                        foreach (FieldInfo fi in fieldList) //遍历枚举字段信息
                        {
                            enumObj = fi.GetValue(null); //获取对应枚举对象
                            if (enumObj != null && (int)enumObj == val)
                            {
                                arrDisplayNameAttr = (DisplayAttribute[])fi.GetCustomAttributes(typeof(DisplayAttribute), false);
                                if (arrDisplayNameAttr != null && arrDisplayNameAttr.Length > 0)
                                {
                                    attrDisplay = arrDisplayNameAttr[0];
                                    if (attrDisplay?.Name?.Length > 0) return attrDisplay.Name;
                                }
                                arrDescriptionAttr = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
                                if (arrDescriptionAttr != null && arrDescriptionAttr.Length > 0 && !string.IsNullOrEmpty(arrDescriptionAttr[0].Description))
                                {
                                    return arrDescriptionAttr[0].Description;
                                }
                                return fi.Name;
                            }
                        }
                    }
                }
            }
            catch { }
            return val.ToString();
        }

        /// <summary>
        /// 获取枚举对象的所有枚举值的编号和名称列表
        /// </summary>
        /// <typeparam name="T">枚举对象</typeparam>
        /// <param name="showDisplay">Name是否采用Display属性</param>
        /// <returns></returns>
        public static List<BaseIntIdNameModel> GetEnumIdNameList<T>(bool showDisplay = false) where T : struct
        {
            List<BaseIntIdNameModel> result = new List<BaseIntIdNameModel>();
            try
            {
                Type enumType = typeof(T);
                if (enumType.IsEnum)
                {
                    FieldInfo[] fieldList = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
                    if (fieldList?.Length > 0)
                    {
                        string name = string.Empty;
                        object? enumObj;
                        DisplayAttribute? attrDisplay;
                        foreach (FieldInfo field in fieldList) //遍历枚举字段信息
                        {
                            attrDisplay = field.GetCustomAttribute<DisplayAttribute>();
                            enumObj = field.GetValue(null); //获取对应枚举对象
                            if (showDisplay && attrDisplay?.Name?.Length > 0)
                            {
                                name = attrDisplay.Name;
                            }
                            else if (!string.IsNullOrEmpty(field.Name))
                            {
                                name = field.Name;
                            }
                            if (enumObj != null)
                            {
                                if (!string.IsNullOrEmpty(name))
                                {
                                    result.Add(new BaseIntIdNameModel()
                                    {
                                        Id = (int)enumObj,
                                        Name = name
                                    });
                                    continue;
                                }
                                string? enumStr = enumObj.ToString();
                                if (!string.IsNullOrEmpty(enumStr))
                                {
                                    result.Add(new BaseIntIdNameModel()
                                    {
                                        Id = (int)enumObj,
                                        Name = enumStr
                                    });
                                }
                            }
                        }
                    }
                }
            }
            catch { }
            return result;
        }
    }
}
